package com.qk.management.service.serviceimpl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qk.common.PageResult;
import com.qk.dto.log.LogDTO;
import com.qk.entity.Log;
import com.qk.management.mapper.LogMapper;
import com.qk.management.mapper.UserMapper;
import com.qk.management.service.LogService;
import com.qk.vo.log.LogVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 上官徵羽
 * @version 1.0
 * @since 2025-10-17 21:51
 */
@Service
public class LogServiceImpl extends ServiceImpl<LogMapper, Log> implements LogService {
    private static final String ID = "id";
    private static final String NAME = "name";
    private static final String OPERATE_USER_NAME = "operateUserName";
    @Autowired
    private UserMapper userMapper;

    @Override
    public PageResult<LogVO> listPage(LogDTO logDTO) {
        Page<Log> page = Page.of(logDTO.getPage(), logDTO.getPageSize());
        LambdaQueryWrapper<Log> wrapper = new LambdaQueryWrapper<>();
        Map<Integer, String> userMap = null;
        if (extracted(logDTO, wrapper)){
            return PageResult.<LogVO>builder()
                .total(page.getTotal())
                .rows(new ArrayList<>())
                .build();
        }
        Page<Log> logPage = this.baseMapper.selectPage(page, wrapper);
        List<Integer> userIds = logPage.getRecords().stream()
                .map(Log::getOperateUserId)
                .filter(ObjectUtil::isNotNull)
                .distinct()
                .toList();
        Page<LogVO> logVO = new Page<>();
        BeanUtils.copyProperties(logPage, logVO,OPERATE_USER_NAME);
        logVO.setRecords(logPage.getRecords().stream()
                .map(log -> {
                    LogVO newLogVO = new LogVO();
                    BeanUtil.copyProperties(log, newLogVO);
                    return newLogVO;
                })
                .collect(Collectors.toList()));
        if (!ObjectUtil.isEmpty(userIds)){
            userMap = getUserMap(null, userIds);
        }
        for (LogVO newLogVO : logVO.getRecords()){
            if (!ObjectUtil.isEmpty(newLogVO.getOperateUserId())){
                assert userMap != null;
                newLogVO.setOperateUserName(userMap.get(Integer.parseInt(newLogVO.getOperateUserId())));
            }
        }
        return PageResult.<LogVO>builder()
                .total(logVO.getTotal())
                .rows(logVO.getRecords())
                .build();
    }

    private boolean extracted(LogDTO logDTO, LambdaQueryWrapper<Log> wrapper) {
        if (!ObjectUtil.isEmpty(logDTO.getOperateUserName())) {
            Map<Integer, String> userMap = getUserMap(logDTO.getOperateUserName(), null);
            if (ObjectUtil.isEmpty(userMap)) {
                return true;
            }
            wrapper.in(Log::getOperateUserId, userMap.keySet());
        }
        return false;
    }

    private Map<Integer, String> getUserMap(String name, List<Integer> ids) {
        List<Map<String, Object>> userList = userMapper.getMap(name, ids);
        return userList.stream().collect(
                Collectors.toMap(
                        map -> Integer.parseInt(map.get(ID).toString()),
                        map -> map.get(NAME).toString()));
    }
}
